use crate::employee::Employee;

pub struct Database {
    employees: Vec<Employee>,
    next_employee_number: i32,
}

impl Database {
    pub fn new() -> Database {
        Database {
            employees: Vec::new(),
            next_employee_number: 1000,
        }
    }

    pub fn add_employee(&mut self, first_name: String, last_name: String) -> &Employee {
        let mut the_employee = Employee::new(first_name, last_name);
        the_employee.set_employee_number(self.next_employee_number);

        self.next_employee_number += 1;

        the_employee.hire();
        self.employees.push(the_employee);

        self.employees.last().expect("Failed to add employee")
    }

    pub fn get_employee_by_number(&mut self, employee_number: i32) -> &mut Employee {
        self.employees
            .get_mut((employee_number - 1000) as usize)
            .expect("invalid employee number")
    }

    pub fn get_employee_by_name(&mut self, first_name: &str, last_name: &str) -> &mut Employee {
        for employee in &mut self.employees {
            if first_name == employee.get_first_name() && last_name == employee.get_last_name() {
                return employee;
            }
        }
        panic!("Employee not found: {} {}", first_name, last_name);
    }

    pub fn display_all(&self) {
        for employee in &self.employees {
            employee.display();
        }
    }

    pub fn display_current(&self) {
        for employee in &self.employees {
            if employee.is_hired() {
                employee.display();
            }
        }
    }

    pub fn display_former(&self) {
        for employee in &self.employees {
            if !employee.is_hired() {
                employee.display();
            }
        }
    }
}
